home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Video
/
World of Video.iso
/
programs
/
sound
/
delitracker_v2.01
/
developer
/
developer.dok
< prev
next >
Wrap
Text File
|
1995-02-13
|
36KB
|
829 lines
$VER: Developer.dok V2.00 (13.04.1994)
Copyright 1994 by Delirium Softdesign
(Peter Kunath and Frank Riffel)
DeliTracker Development Documentation
1.ÜBERBLICK
2.PLAYER
2.1 Normale Player
2.2 Custom Module
2.3 Interrupts
3.GENIES
3.1 Generic Kind
3.2 Converter
3.3 Decruncher
3.4 NotePlayer
4.TAGS
5.DELITRACKER SUPPORT FUNKTIONEN
1.ÜBERBLICK
DeliTracker kann mit externen Programmodulen erweitert werden. Diese
sehen vom DOS aus betrachtet genauso aus wie normale Objectfiles, mit
dem Unterschied allerdings, daß sie am Anfang des ersten Hunks eine
spezielle Struktur besitzen. Wenn DeliTracker ein solches Programmodul
nachlädt, wertet er diese Struktur aus. Sie besteht aus drei Teilen:
Einem Longword mit Code, zwei Longwords als Identifier und als letztes
einem Pointer auf ein Tagarray. Das erste Longword enthält normalerweise
moveq #-1,d0 gefolgt von einem rts Befehl. Dies soll einen Absturz
verhindern, wenn ein Player oder Genie irrtümlich vom Benutzer gestartet
wird. Um ein Programm zu erzeugen, das auch ohne DeliTracker lauffähig
ist, muß in das erste Longword in einen bra.w geändert werden, der dann
den eigentlichen Startupcode anspringt. Um die charakteristische Struktur
zu erzeugen sollte das PLAYERHEADER Macro aus 'deliplayer.i' verwendet
werden. Es hat zwei Parameter: einen Pointer auf ein Tagarray und
optional einen Pointer auf den Startupcode.
PLAYERHEADER <tagarray>,[startup]
tagarray Pointer auf ein Tag Array, das mit TAG_DONE
abgeschlossen sein muß.
startup Pointer auf einen optionalen Startupcode. Nur
notwendig, wenn das Programmodul auch ohne
DeliTracker lauffähig sein soll.
Bemerkung: Wenn der Startupcode angesprungen
wird, muß die gesamte Initialisierung etc. ohne
DeliTracker durchgeführt werden. In den meisten
Fällen macht die Startup Option wenig Sinn und
wird deshalb auch kaum benutzt.
Die Tagliste enthält dabei alle Informationen, die DeliTracker wissen
muß. Wir verwenden ein Tagarray deshalb, weil es sehr flexibel und leicht
erweiterbar ist. Zusätzlich können die externen Programmodule noch die
GlobalStructure sowie die eingebauten Supportfunktionen benutzen. Im
Moment unterscheidet DeliTracker zwei verschiedene Typen von externen
Programmodulen:
1) Player, um Module zu identifizieren und zu spielen
2) Genies können viele andere Dinge machen. Unter anderem Module
konvertieren, Dateien entpacken oder Informationen anzeigen.
Beide Arten können synchron oder asynchron laufen. Unter synchron
versteht man, daß der Player oder das Genie nicht als eigener Prozess
läuft. DeliTracker benutzt in diesem Fall echte Funktionsaufrufe (jsr)
zur Kommunikation. Im asynchronen Modus startet DeliTracker den Player
oder das Genie als eigenen Prozess und verwendet dann Messages um
Funktionen der externen Programmodule aufzurufen. Im allgemeinen laufen
Genies asynchron und Player synchron. Wenn ein Player oder ein Genie
asynchron läuft, dann muss man es durch Senden eines CTRL-C Signals an
den Prozeß beenden können. Offensichtlich sind DeliPlayer und DeliGenies
also sehr ähnlich. Sie werden von DeliTracker auch ziemlich gleich
verwaltet, wenn auch in zwei verschiedenen Listen. Jedes externe
Programmodul bei dem ein DTP_CustomPlayer, DTP_Check1 oder DTP_Check2
Tag benutzt wird, ist ein Player. Der Rest sind Genies.
Wenn eine GUI vorhanden ist, sollten normalerweise folgende Menüpunkte
zur Verfügung stehen:
Project
About A ? Kurzinformation über das Programmodul
==============
Save Prefs A S Speichern der aktuellen Einstellungen
==============
Hide A H GUI verbergen
==============
Quit A Q Genie beenden (ebenso wie CTRL-C)
Settings
Activate A A Aktiviert das Fenster beim Öffnen des GUI
Popup A P Öffnet das GUI nach dem Laden
==============
Other settings Hier können je nach Bedarf weitere
·············· Einstellungen folgen.
Ein paar Anmerkungen:
Bevor man einen DeliPlayer schreibt, sollte man sich die migelieferten
Beispielsourcen genau durchlesen. Um einen besseren Überblick davon zu
bekommen, wann und in welcher Reihenfolge DeliTracker die Funktionen des
Players aufruft, kann man den 'Testplayer.s' Source benutzen. Wenn eine
Konfigurationsdatei abgespeichert werden kann, sollte sie nicht nach
ENV:, sondern in das DeliTracker Konfiguartionsverzeichnis abgespeichert
werden. Der Pfad des Konfiguartionsverzeichnisses kann steht in der ENV-
Vaiable 'DeliConfig'. Falls diese nicht vorhanden ist, sollte stattdessen
'PROGDIR:DeliConfig' zum Abspeichern benutzt werden. Ein Player sollte
außerdem den Zustand der LED (Lowpass-Filter) unbeeinflußt lassen, da im
Optionfenster eine entsprechende Funktion existiert. Wenn von DeliTracker
eine Funktion des Players aufgerufen wird (außer bei den Interrupt-
Funktionen DTP_Interrupt und DTP_NoteSignal), enthält das Register a5
einen Pointer auf die Globale Struktur (Base). Da DeliTracker vor Aufruf
einer Routine (außer bei DTP_Interrupt und DTP_NoteSignal) alle Register
sichert, dürfen diese verändert werden.
2.PLAYERS
Es ist relativ einfach, eine Replayroutine an DeliTracker anzupassen.
Alles was Sie tun müssen ist ein wenig Interfacecode zu schreiben. Dies
ist im allgemeinen recht einfach, denn DeliTracker stellt ihnen viele
hilfreiche Routinen zur Verfügung. Um ein neues Soundsystem anzupassen,
benötigen Sie zum einen den Quellcode oder ein linkbares Objektfile der
Replayroutine, zum anderen sollten mindestens ca. 5 Module zum Testen der
Funktionstüchtigkeit des Players vorhanden sein. Ganz am Anfang eines
Players muß sie charakteristische Struktur stehen. DeliTracker unter-
scheidet dann zwei Arten von Playern: normale Player und Custom Module.
2.1 Normale Player
Normale Player identifizieren und spielen Module. Sie müssen immer eine
Check Routine besitzen. Der schematische Aufbau eines normalen Players
ist folgendermassen:
{ Playerheader } Kennzeichnet das Object als Player.
{ TagArray } Beschreibung, was der Player kann.
{ Interfacecode } Playername/Registerumsetzung/Checkcode u.ä.
{ Replaycode } Eigentlicher Musikabspielcode.
{ evtl. Daten } und Daten
Damit der Player die einzelnen Module unterscheiden kann, befindet sich
in jedem Player eine Erkennungsroutine, die auf ein zugehöriges Modul
testet und DeliTracker mitteilt, ob der Player dieses Modul spielen
kann oder nicht. Diese Routine prüft auf Stellen im Modul, die bei allen
Modulen eines Formats gleich sind. So z.B. auf 'M.K.' bei Offset $438
in ProTracker-Modulen. Nur auf einige wenige Sprungbefehle zu Prüfen
reicht im allgemeinen nicht aus, da viele Modulformate mit eingebauter
Abspielroutine Sprungbefehle am Anfang haben und der Player möglicher-
weise das falsche Modul erkennen könnte, was in den meisten Fällen zum
Absturz führt! Deshalb sollte die Check Routine auch eingehend getestet
werden. Es gibt zwei Typen von Check Funktionen, genau eine davon muß
der Player verwenden.
a) DTP_Check1: Diese Check Funktion wird aufgerufen, wenn DeliTracker
1K des Files geladen hat. Der Vorteil ist daß sich auch Player
realisieren lassen, die das Modul selbst nachladen. Der Nachteil ist,
daß der Player dann nicht von den Entpackroutinen in DeliTracker
profitiert. Meistens ist es deshalb schwerer, einen solchen Player zu
schreiben. Man sollte diesen Typ nur für Härtefälle verwenden, z.B.
wenn das Modul vom Player selbst geladen werden muß.
b) DTP_Check2: Diese Check Routine wird aufgerufen, wenn das Modul
geladen und ggf. entpackt ist. Da ein Player mit dieser Check Funktion
im allgemeinen leichter zu schreiben ist, sollte im Normalfall diese
Check Routine verwendet werden.
Egal welche Checkfunktion verwendet wird, wenn der Player das Modul
erkannt hat, muß er in d0.l=0 zurückliefern, wenn nicht d0.l<>0.
2.2 Custom Module
Custom Module sind keine Module im herkömmlichen Sinn, sondern
besondere Player, die ein Modul beinhalten. Sie haben auch keine
Check Funktion, stattdessen muß der DTP_CustomPlayer Tag verwendet
werden. Mit diesem Interface kann man auch die ausgefallensten
Moduleformate an DeliTracker anpassen. Sollten jedoch mehrere Module
dieses Typs existieren, ist es in jedem Fall ratsam, einen richtigen
Player zu schreiben.
{ Playerheader } Kennzeichnet das Object als Player.
{ TagArray } Beschreibung, was der Player kann.
{ Interfacecode } Routinen zur Registerumsetzung u.ä.
{ Replaycode } Eigentlicher Musikabspielcode.
{ evtl. Daten } und Daten
{ SOUND DATEN } Das eigentliche Modul
2.3 Interrupts
Hier gibt es eine Einteilung in zwei verschiedene Typen.
a) Player die den DeliTracker Interrupt verwenden
Vorteil: Der Player ist vom Videomodus unabhängig.
Besitzt automatisch die Faster/Slower Funktion.
Kein Aufwand für den Interrupt (Code + Interruptstruktur).
Automatisch kompatibel zum serial.device.
Nachteil: Der Interrupt kommt nicht synchron zum VBlank. (Dies führt
nur in den seltensten Fällen zu Problemen.)
b) Player die ihren eigenen Interrupt erzeugen.
Vorteil: Es können andere Interruptquellen benutzt werden
(z.B. AudioIRQ).
Nachteil: Erhöhter Aufwand, bei VBlank nicht mehr unabhängig vom
Videomodus.
Wenn ein eigener Timerinterrupt verwendet wird, sollte die CIAB
(wg. OS2.0) und die entsprechenden Resourcefunktionen verwendet werden.
Außerdem ist es sehr sinnvoll die Replayroutine nicht direkt im CIA-B
TimerInterrupt laufen zu lassen, sondern im Timerinterrupt einen
Soft-Interrupt mittels Cause() zu generieren. In diesem SoftInt kann
man dann die eigentliche Replayroutine ablaufen lassen. Das hat den
Vorteil, daß man wesentlich kompatibler zum serial.device ist. Dies
liegt daran, daß SoftInt eine niedrigere Priorität als der der RBF
(Read Buffer Full) Interrupt hat d.h. erst wird der serielle Port
bedient, dann erst die Replayroutine. Es wird davor gewarnt, direkt
in die Interruptvektoren zu schreiben! Vom Betriebssystem werden dafür
die Funktionen AddIntServer() und SetIntVector() zur Verfügung
gestellt.
3.GENIES
Die Funktionalität von DeliTracker kann mit Hilfe von Genies auf viele
verschiedene Arten erweitert werden. Im Moment existieren vier
grundsätzlich verschiedene Einsatzgebiete für Genies: die Ausgabe von
Noten (nicht zu verwechseln mit Playern), das Entpacken und Konvertieren
von Modulen und schließlich das Analysieren des aktuellen Moduls.
3.1 Generic Kind
Diese Art von Genies ist nicht auf spezielle Aufgaben beschrängt. Es
kann z.B. diverse Informationen über das Modul anzeigen. Natürlich
darf weder das Modul noch die Globale Struktur zur Gewinnung dieser
Informationen verändert werden. Überlicherweise benutzt dieser Genie-
Typ DTP_InitPlay/DTP_EndPlay um zu erfahren, wenn ein neues Modul
gespielt wird, zusätzlich evtl. auch noch DTP_StartInt/DTP_StopInt.
3.2 Converter
Diese Genies verändern ein Modul. So kann man z.B. das Format des
Moduls oder seine Länge ändern. Für diese Aufgabe gibt es einen
speziellen Tag, nämlich DTP_Convert. Er enthält die Adresse der
Convert-Funktion.
3.3 Decruncher
Diese Art von Genies erweitert die dtg_LoadFile() Funktion von
DeliTracker. Da sich dieses Interface noch ändern wird, ist es im
Moment noch nicht dokumentiert.
3.4 Noteplayer
Diese Genies haben die Aufgabe, 'Noten' ggf. zu konvertieren und sie
auf der jeweiligen Audiohardware auszugeben. Dieses Interface ist zur
Zeit noch Änderungen unterworfen und deshalb noch nicht dokumentiert.
4. TAGS
Außer den SystemTags (TAG_DONE, TAG_IGNORE, TAG_MORE, TAG_SKIP) dürfen
folgende Tags verwendet werden:
DTP_CustomPlayer (BOOL) - dieser Tag deklariert einen Player als
Customplayer.
Bei Verwendung dieses Tags sind folgende Tags dann
bedeutungslos: DTP_PlayerVersion
DTP_PlayerName
DTP_Creator
DTP_Check1
DTP_Check2
DTP_ExtLoad
DTP_Config
DTP_UserConfig
DTP_RequestDTVersion (WORD) - damit kann man sicherstellen, daß
mindestens eine bestimmte Version von DeliTracker
vorhanden ist. Dieser Tag muß angegeben werden, wenn
bei den DeliTrackerGlobals neue Funktionspointer
hinzugekommen sind und diese vom Player benutzt werden.
ti_Data ist dabei die Playerrevision.
DTP_RequestKickVersion (ULONG) - wenn dieser Tag angegeben ist, wird
der Player nur noch von von DeliTracker geladen, wenn
mindestens die angeforderte Kickstart Version vorhanden
ist.
DTP_PlayerVersion (WORD) - Tag, der die Versionsnummer (high word) und
die Revisionsnummer (low word) des Players enthält. Bei
zwei Playern mit dem gleichen Playernamen wird derjenige
mit der größeren Revisionsnummer geladen.
DTP_PlayerName (STRPTR) - ti_Data enthält den Pointer auf den Namen des
Players. Dieser String kann zwar beliebig lang sein aber
zur Zeit werden nur die ersten 24 Zeichen angezeigt. Dieser
Tag muß existieren!
DTP_Creator (STRPTR) - Pointer auf den Namen des Autors. Dieser wird im
Playerfenster im Playerinfofeld angezeigt. Der String
kann $A als Zeilenumbruch enthalten.
DTP_Check1 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
aufgerufen wird, wenn 1024 Bytes des Moduls geladen sind.
Wird das Modul erkannt, liefert sie d0=0, ansonsten d0<>0.
DTP_Check2 (FPTR) - Pointer auf eine Modulerkennungsroutine, die
aufgerufen wird, wenn das komplette Modul geladen und evtl.
entpackt ist. Wird das Modul erkannt, liefert sie d0=0,
ansonsten d0<>0.
DTP_ExtLoad (FPTR) - Pointer auf eine optionale Laderoutine für Module.
Ist kein Fehler aufgetreten, wird d0=0 zurückgegeben, sonst
d0<>0. Hinweis: Achten Sie darauf, daß im Fehlerfall alle
allocierten Ressourcen (Memory, Locks, ...) wieder
freigegeben werden, da dann keine weiteren Playerfunktionen
mehr angesprungen werden.
DTP_Interrupt (FPTR) - Pointer auf eine Interruptroutine, die mittels
eines Timerinterrupts standardmäßig alle 1/50 sec
aufgerufen wird. Dies ist die Standardmethode, um mit der
richtigen Abspielgeschwindigkeit im PAL/NTSC/Productivity
Videomodus zu spielen. Wenn keine DTP_Faster/DTP_Slower
Tags angegeben sind, übernimmt DeliTracker dies durch
Verändern der Interruptfrequenz. Dieser Tag kann auch nicht
existieren, dann müssen aber DTP_StartInt/DTP_StopInt
vorhanden sein !
DTP_Stop (FPTR) - Pointer auf eine optionale Stoproutine. Wenn dieser Tag
nicht vorhanden ist, verfährt DeliTracker folgendermaßen:
Interrupt stoppen (DTP_StopInt)
Sound Cleanup (DTP_EndSnd)
Song initialisieren (DTP_InitSnd)
Ansonsten hat diese Routine die Aufgabe, einen evtl.
spielenden Song anzuhalten und so zu initialisieren, daß
dieser beim nächsten Starten des Interrupts von Anfang an
zu spielen beginnt.
DTP_Config (FPTR) - Pointer auf eine optionale Initialisierungsroutine.
Diese wird nur einmal unmittelbar nach dem Laden des
Players aufgerufen. Mögliche Anwendungen: Laden einer
playerspezifischen Konfigurationsdatei. Ist kein Fehler
aufgetreten, muss d0=0 zurückgegeben werden, sonst
d0<>0. Hinweis: Im Fehlerfall wird der Player von
DeliTracker wieder entfernt!
DTP_UserConfig (FPTR) - Pointer auf eine optionale Initialisierungs-
routine. Diese wird nur dann aufgerufen, wenn der User den
Player im Setupfenster anwählt und das 'Config' Gadget
drückt. Mögliche Anwendungen: Öffnen eines Fensters zum
Setzen weiterer Optionen wie z.B. Instrumentenpfad und
Abspeichern einer playerspezifischen Konfigurationsdatei.
DTP_SubSongRange (FPTR) - Überholt, bitte DTP_NewSubSongRange benützen!
Dieser Tag sollte angegeben werden, wenn der Player
MultiModule unterstützt. ti_Data zeigt dabei auf eine
Routine, die als Returnwert in d0 die minimale und
in d1 die maximale Subsongnummer zurückgeben muß.
Hinweis: Wenn möglich sollte dieser Tag (evtl. zusammen
mit DTP_SubSongTest) anstelle von DTP_NextSong/DTP_PrevSong
verwendet werden.
DTP_InitPlayer (FPTR) - Pointer auf eine optionale Initialsierungs-
routine, die aufgerufen wird, wenn ein Modul erfolgreich
geladen wurde. Tritt kein Fehler auf, liefert sie d0=0,
ansonsten d0<>0. Hier muß die Allocation der Audiokanäle
stattfinden! (DeliTracker stellt dafür eine eigene Routine
zur Verfügung) Falls der Player Multi-Module unterstützt,
muß hier dtg_SndNum(a5) auf die erste Subsongnummer gesetzt
werden. Falls eine Routine für DTP_SubSongRange existiert,
macht DeliTracker das automatisch (d.h. die Initialisierung
von dtg_SndNum(a5) kann weggelassen werden).
DTP_EndPlayer (FPTR) - Pointer auf eine optionale Cleanuproutine, die
aufgerufen wird, wenn das Modul aus dem Speicher entfernt
wird. Hier muß die Freigabe der Audiokanäle stattfinden!
(DeliTracker stellt dafür eine eigene Routine zur
Verfügung)
DTP_InitSound (FPTR) - Pointer auf eine optionale Initialsierungsroutine.
Diese muß das Modul initialisieren, so daß beim Starten des
Interrupts der Song von Anfang an zu spielen beginnt.
DTP_EndSound (FPTR) - Pointer auf eine optionale Cleanuproutine. Diese
kann z.B. die Lautstärkeregister und die Audio-DMA
rücksetzen.
DTP_StartInt (FPTR) - Pointer auf eine Initialsierungsroutine, die
existieren muß, wenn DTP_Interrupt nicht vorhanden ist.
In diesem Fall muß hier der Sound gestartet werden.
DTP_StopInt (FPTR) - Pointer auf eine Cleanuproutine, die existieren muß,
wenn DTP_Interrupt nicht vorhanden ist. In diesem Fall muß
hier der Sound gestoppt werden.
DTP_Volume (FPTR) - Pointer auf eine Funktion, welche die Lautstärke neu
setzt. Die Funktion wird aufgerufen, wenn die Volume neu
gesetzt wird (Slider, ARexx) und beim Initialisieren des
Moduls vor DTP_InitSnd. Die Mastervolume steht in
dtg_SndVol(a5). Die Mastervolume ist dabei der maximale
Volumewert. Die effektive Volume errechnet sich also
durch: VOL_eff = (( dtg_Volume(a5) * modulevolume )>>6)
Näheres siehe Beispielsourcen.
DTP_Balance (FPTR) - Pointer auf eine Funktion, welche die Balance neu
setzt. Die Funktion wird aufgerufen, wenn die Balance neu
gesetzt wird (Slider, ARexx) und beim Initialisieren des
Moduls vor DTP_InitSnd. Die Balance für die linken Kanäle
steht in dtg_SndLBal(a5), für die rechten Kanäle in
dtg_SndRBal(a5). Hinweis: Alle Player die Balance unterstützen
können auch Volume! Man verwendet dann die gleiche Routine
zum Setzen der Volume&Balance. Die linke Volume errechnet
sich wie folgt: (( dtg_Volume(a5) * dtg_SndLBal(a5) )>>6)
Entsprechendes gilt für rechts.
DTP_Faster (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
beschleunigt.
DTP_Slower (FPTR) - Pointer auf eine Funktion, die den Abspielvorgang
verlangsamt.
DTP_NextPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
um eins erhöht.
DTP_PrevPatt (FPTR) - Pointer auf eine Funktion, die den Patternzeiger
um eins erniedrigt.
DTP_NextSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
den nächsten Subsong setzt und diesen spielt.
(Falls vorhanden)
DTP_PrevSong (FPTR) - Pointer auf eine Funktion, die Subsongnummer auf
den vorhergehenden Subsong setzt und diesen spielt.
(Falls vorhanden)
;--- tags in revision 14 or higher (distributed as Release 1.35) ---
DTP_SubSongTest (FPTR) - Dieser Tag wird nur ausgewertet, wenn schon der
Tag DTP_SubSongRange angegeben wurde. ti_Data zeigt dabei
auf eine Routine, die als Returnwert in d0 einen Boolschen
Wert zurückliefert. Dieser gibt an, ob der SubSong mit
Nummer dtg_SndNum(a5) gültig ist (d0=0) oder nicht (d0<>0).
Dieser Tag ist nur bei den Playern nötig, bei denen nicht
jeder SubSong (innerhalb der durch DTP_SubSongRange
festgelegten Grenzen) benutzt ist.
;--- tags in revision 16 or higher (distributed as Release 2.00) ---
DTP_NewSubSongRange (FPTR) - erweiterter Ersatz für DTP_SubSongRange.
Dieser Tag sollte angegeben werden, wenn der Player
MultiModule unterstützt. ti_Data zeigt dabei auf eine
Funktion, die als Result einen Pointer auf ein Array
mit drei WORDs zurückliefert: Das erste Word enthält
die Nummer des Subsongs, der als erstes gespielt werden
soll. Das zweite enthält die minimale und das dritte die
maximale Subsong Nummer. In den meisten Fällen ist das
erste und das zweite WORD identisch.
DTP_DeliBase (APTR) - die Adresse eines Pointers, wo DeliTracker einen
Pointer auf die DeliGlobals ablegt.
DTP_Flags (ULONG) - enthält verschiedene Flags.
Derzeit sind folgende Flags definiert:
PLYF_CUSTOM - der Player ist ein Customplayer
PLYF_SONGEND - dieser Player unterstützt Songend
DTP_CheckLen (ULONG) - Länge des Check Codes. Dieser Tag darf nur benutzt
werden, wenn der Checkcode PC-relativ und reentrant ist!
Wenn der Tag benutzt wird, lagert DeliTracker den Player in
LowMem-Situationen aus.
DTP_Description (APTR) - Pointer auf einen String mit einer Beschreibung,
was der Player bzw. das Genie tut und welche besonderen
Fähigkeiten es hat. Dieser String kann $A als Zeilenumbruch
enthalten.
DTP_Decrunch (FPTR) - private, still under development!
DTP_Convert (FPTR) - Pointer auf eine Routine zum Konvertieren eines
Moduls. Diese Routine wird aufgerufen, wenn das Modul
geladen und ggf. entpackt ist. Sie dient dazu, das Modul
in ein neues Format umzukonvertieren. Die Konvertier-
Routine funktioniert üblicherweise folgendermassen:
1) Ausgangs-Format erkennen
2) Speicher für Ziel-Format mit dtg_AllocListData()
belegen
3) Das Modul vom Ausgangsformat ins Zielformat
konverieren
Diese Routine muß NULL zurückliefern, wenn das Modul
erfolgreich konvertiert wurde (success), ansonsten -1
(error). Auf gar keinen Fall darf das Ausgangs-Modul von
der Konvertier-Funktion verändert werden!
Bemerkung: für temporäre Speicher-Allocationen sollte man
die entsprechenden Exec-Funktionen benutzen, der Speicher
für das Ziel-Modul muß aber in jedem Fall mit der Support
Funktion dtg_AllocListData() belegt werden!
DTP_NotePlayer (APTR) - private, still under development!
DTP_NoteStruct (APTR) - private, still under development!
DTP_NoteInfo (APTR) - private, still under development!
DTP_NoteSignal (FPTR) - private, still under development!
DTP_Process (FPTR) - Pointer auf einen Code, der als Prozess gestartet
werden soll. Wenn dieser Tag verwendet wird, startet
DeliTracker den Player bzw. das Genie als eigenen Prozess.
DTP_Priority (BYTE) - Priorität des zu startenden Prozesses. Nur in
Verbindung mit DTP_Process sinnvoll.
DTP_StackSize (ULONG) - Stack-Größe des zu startenden Prozesses. Nur in
Verbindung mit DTP_Process sinnvoll.
DTP_MsgPort (APTR) - Adresse eines Pointer, wo DeliTracker die Adresse
des Ports ablegt, an den dann die Messages geschickt
werden. Nur in Verbindung mit DTP_Process sinnvoll.
DTP_Appear (FPTR) - Pointer auf eine Routine die die GUI des Players bzw.
Genies öffnet/aktiviert. Als Returnwert muß der alte
Windowzustand (<>0 wenn das Fenster auf war, ansonsten 0)
zurückgeliefert werden. Bemerkung: Stellen Sie sicher, daß
die GUI auf dem richtigen Screen geöffnet wird! (benützen
Sie dazu die dtg_LockPubScreen() und dtg_UnLockPubScreen()
Funktionen).
DTP_Disappear (FPTR) - Pointer auf eine Routine, die die GUI schliesst.
Diese Routine muss den alten Windowzustand (<>0 wenn das
Fenster auf war, ansonsten 0) zurückgeliefern.
DTP_ModuleName (APTR) - Adresse eines Pointers, der auf den tatsächlichen
Namen des Moduls zeigt (dieser String muß mit NULL
abgeschlossen sein). Dieser Tag ist nur für Player sinnvoll
und wird nach InitPlay() ausgewertet.
DTP_FormatName (APTR) - Adresse eines Pointers, der auf den Namen des
urspünglichen Modulformats zeigt (dieser String muß mit
NULL abgeschlossen sein). Dieser Tag ist nur für Genies
sinnvoll und wird nach der Convert() Funktion ausgewertet.
5.DELITRACKER SUPPORT FUNKTIONEN
DeliTracker stellt zur Erleichterung der Playeranpassung einige
Funktionen zur Verfügung. Eine Funktion wird wie folgt aufgerufen:
move.l dtg_XXX(a5),a0
jsr (a0)
Alle folgenden Funktionen außer dtg_SongEnd, dtg_SetTimer und
dtp_NotePlayer verwenden d0/d1/a0/a1 als Scratchregister. In a5 muß bei
allen Aufrufen (außer bei dtg_SongEnd, dtg_SetTimer und dtp_NotePlayer)
der Pointer auf die Base stehen. Derzeit existieren folgende Funktionen:
dtg_GetListData
SYNOPSIS
memory size = dtg_GetListData(number)
a0 d0 d0.l
FUNCTION
Liefert Adresse und Länge eines mit LoadFile() geladenen
Files.
INPUTS
number - Nummer eines Files beginnend mit 0 für das vom
User selektierte File.
RESULT
memory - ein Pointer auf die Startadresse des Files im
Speicher oder NULL im Fehlerfall.
size - Länge des Files in Bytes bzw. 0 im Fehlerfall.
dtg_LoadFile
SYNOPSIS
success = dtg_LoadFile(name)
FUNCTION
Lädt und entpackt ggf. das angegebene File ins Chip-
Memory. (Hinweis: diese Funktion ergänzt automatisch,
falls das File mit dem angegebenen Namen nicht geöffnet
werden konnte '.pp','.im' und '.xpk')
INPUTS
name - der Filename steht in einem internen Buffer (seine
Adresse steht in dtg_PathArray)
RESULT
success - alles ok d0.l=0, sonst d0.l<>0.
dtg_CopyDir
SYNOPSIS
dtg_CopyDir()
FUNCTION
Kopiert das Directory des von User angewählten Files an das
Ende des Strings, auf den dtg_PathArray(a5) zeigt.
dtg_CopyFile
SYNOPSIS
dtg_CopyFile()
FUNCTION
Kopiert den Filenamen des von User angewählten Files an das
Ende des Strings, auf den dtg_PathArray(a5) zeigt.
dtg_CopyString
SYNOPSIS
dtg_CopyString(string)
a0
FUNCTION
Kopiert den String, auf den das Register a0 zeigt, an das
Ende des Strings, auf den dtg_PathArray(a5) zeigt.
INPUTS
string - der Pointer auf den anzuhängenden String steht
in a0
dtg_AudioAlloc
SYNOPSIS
success = dtg_AudioAlloc()
FUNCTION
Belegt alle Audiokanäle.
RESULT
success - alles ok d0.l=0, sonst d0.l<>0.
dtg_AudioFree
SYNOPSIS
dtg_AudioFree()
FUNCTION
Gibt die mit dtg_AudioAlloc belegten Audiokanäle wieder
frei.
dtg_StartInt
SYNOPSIS
dtg_StartInt()
FUNCTION
Startet den Soundinterrupt. (Falls er nicht schon läuft.)
Falls DTP_Interrupt existiert, startet DeliTracker einen
Timerinterrupt, ansonsten wird DTP_StartInt aufgerufen.
dtg_StopInt
SYNOPSIS
dtg_StopInt()
FUNCTION
Stoppt den Soundinterrupt. (Falls er nicht schon angehalten
ist.) Falls DTP_Interrupt existiert, stoppt DeliTracker
seinen Timerinterrupt, ansonsten wird DTP_StopInt
aufgerufen.
dtg_SongEnd
SYNOPSIS
dtg_SongEnd()
FUNCTION
Signalisiert DeliTracker, daß das Modul einmal komplett
gespielt wurde. Diese Funktion verändert keine Register
und darf auch von Interrupts aufgerufen werden.
dtg_CutSuffix
SYNOPSIS
dtg_CutSuffix()
FUNCTION
Entfernt am Ende des Strings, auf den dtg_PathArray(a5)
zeigt ggf. die Endung '.pp', '.im' oder '.xpk'
;------ extensions in revision 14 (distributed as Release 1.34)
dtg_SetTimer
SYNOPSIS
dtg_SetTimer()
FUNCTION
Programmiert den CIA-Timer mit dem Wert, der sich in
dtg_Timer(a5) befindet. Diese Funktion verändert keine
Register und darf auch von Interrupts aufgerufen werden.
;------ extensions in revision 15 (distributed as Release 1.37)
dtg_WaitAudioDMA
SYNOPSIS
dtg_WaitAudioDMA()
FUNCTION
Diese Funktion wartet eine bestimmte Zeit lang. Die
Zeitspanne sollte für die Audio Hardware normalerweise
groß genug sein, um neue Werte zu laden. Dieser Aufruf ist
nur erlaubt, wenn der interne Timer-Interrupt benutzt wird.
Er kann anstelle der üblichen dbra oder Rasterline
Warteschleifen benutzt werden. Diese Funktion verändert
keine Register.
BUGS
Wenn der Player auch Periods unterstützt, die viel größer
als 1000 sind, wird evtl. nicht lange genug gewartet.
;------ extensions in revision 16 (distributed as release 2.00)
dtg_LockScreen
SYNOPSIS
screen = dtg_LockScreen()
(d0)
FUNCTION
Lockt den Screen auf dem DeliTracker läuft (ist immer
ein Pubscreen).
RESULT
Pointer auf den Screen in d0 oder NULL im Fehlerfall.
dtg_UnlockScreen
SYNOPSIS
dtg_UnlockScreen()
FUNCTION
Diese Function unlockt den Screen, auf dem DeliTracker
läuft. Hinweis: diese Funktion keinesfalls öfters aufrufen
als dtg_LockScreen()!).
dtg_NotePlayer
SYNOPSIS
dtg_NotePlayer()
FUNCTION
Dieser Aufruf spielt die Noten, die in der aktuellen
NoteStruct Struktur angegeben sind. Die Funktion darf
nicht aufgerufen werden, wenn der aktive Player keine
NotePlayer Structur hat.
Hinweis: Dieser Aufruf sichert alle Register und darf
sogar von Interrupts aufgerufen werden, solange das
Interrupt Level 4 oder kleiner ist.
INPUTS
aktuelle NoteStruct.
dtg_AllocListData
SYNOPSIS
memory = dtg_AllocListData(byteSize,Flags)
(d0) (d0.l) (d1.l)
FUNCTION
Dies ist die Funktion, um Modul-spezifischen Speicher von
Playern oder Genies aus zu belegen. Es gibt die Möglichkeit
anzugeben, ob die Allocation im Chipmem oder Publicmem
gemacht werden soll. Wenn die Allocation erfolgreich war,
merkt DeliTracker sich den Memblock und man kann mit der
Funktion dtg_GetListData() die Adresse und die Größe des
Blocks erfahren.
INPUTS
byteSize - Größe des gewünschten Blocks in Bytes.
Flags - die Flags werden an AllocMem() weitergereicht.
RESULT
Ein Pointer auf den allocierten Memoryblock wird in d0
zurückgeliefert. Wenn nicht genug freier Speicher vorhanden
ist, um die Anforderung zu erfüllen, wird Null
zurückgegeben. Der Pointer muß auf jeden Fall getestet
werden und darf nur benutzt werden, wenn er ungleich Null
ist.
dtg_FreeListData
SYNOPSIS
dtg_FreeListData(memoryBlock)
(a1)
FUNCTION
Gibt einen Speicherblock frei, der mit AllocListData(),
allociert wurde.
INPUTS
memoryBlock - Pointer auf den Speicherblock, darf auch
NULL sein.